// 词云图
import React from 'react';
import { WordCloud } from '@antv/g2plot';
import { defaultData } from './mock';
import { getComponentData } from 'src/services/AnalyseManage';
import { WD_TYPE, DL_TYPE } from 'src/pages/AnalyseManage/EditReport/components/EditorDataType/EnumConfig';
import { ChartService, IProps } from 'src/pages/AnalyseManage/EditReport/components/ChartsType/components/ChartService';
import { CHART_LINK } from 'src/pages/AnalyseManage/EditReport/topics';
import PubSub from 'pubsub-js';
import { digitFormat, isNumber } from 'src/libs/utils';

export default class WordCloudChart extends ChartService {
	state = {
		chartEl: null,
		data: defaultData,
		eventToken: [],
		dependencies: [],	//	图表联动参数
		isRender: false,
		precision: '',
		dataUnit: ''
	};

	initEvent = async () => {
		const { data } = await this.getConditionData();
		this.setState( {
			data: data,
		}, () => {
			const line = new WordCloud( this.props.id, this.getConfig() );
			line.render();
			this.setState( {
				chartEl: line,
				isRender: true
			} );

			//	数据联动 组装联动参数
			line.on( 'element:click', ( ev ) => {
				if( !this.props.config.mutual.isChainAvailable ) return;

				const intervalElement = ev.target.get( 'element' );
				const data = intervalElement.getModel().data; // 单条数据
				console.log( data );
				const dimension = this.props.config.data.chartCharField;
				if( !dimension || dimension.length === 0 ) return;
				const dependencies = dimension.map( ( item, index ) => {
					return {
						formatType: item.formatType,
						id: [ item.name ],
						quota: item.modelType === WD_TYPE ? 'WD' : 'DL',
						symbol: 'EQ',
						value: [ data.text ]		//	从原数据中找到item，一一对应字段
					};
				} );

				PubSub.publish( CHART_LINK, {
					publisherId: this.props.id,
					listenerIds: this.props.config.mutual.chartsChainIds,
					dimension: dependencies,
					tableCode: this.props.config.data.tableCode
				} );
			} );
		} );
	};

	getSnapshotBeforeUpdate( prevProps: Readonly<IProps>, prevState: Readonly<{ dependencies: any }> ): any | null {
		let { config } = this.props;
		let changeObj = Object.create( null );
		const prevDataConfig = prevProps.config.data, currentDataConfig = config.data;

		//	判断数据字段是否变化了
		if ( JSON.stringify( prevDataConfig.filterFields ) !== JSON.stringify( currentDataConfig.filterFields ) ||
			JSON.stringify( prevDataConfig.filterConditions ) !== JSON.stringify( currentDataConfig.filterConditions ) ||
			JSON.stringify( prevDataConfig.chartCharField ) !== JSON.stringify( currentDataConfig.chartCharField ) ||
			JSON.stringify( prevDataConfig.chartCharSize ) !== JSON.stringify( currentDataConfig.chartCharSize ) ||
			JSON.stringify( this.state.dependencies ) !== JSON.stringify( prevState.dependencies ) ) {
		   changeObj.needDataChange = true;
	   }

		//	判断样式是否改变
		if ( JSON.stringify( prevProps.config.style ) !== JSON.stringify( config.style ) ) {
			changeObj.needStyleChange = true;
		}

		return changeObj;
	}
	shouldComponentUpdate( nextProps: Readonly<IProps>, nextState: Readonly<{ dependencies: any }>, nextContext: any ): boolean {
		if ( JSON.stringify( nextProps ) !== JSON.stringify( this.props ) ||
			JSON.stringify( this.state.dependencies ) !== JSON.stringify( nextState.dependencies ) ) return true;
		return false;
	}

	async componentDidUpdate( prevProps: Readonly<IProps>, prevState: Readonly<{}>, snapshot?: any ) {

		if ( snapshot.needStyleChange ) {
			this.state.chartEl.update( this.getConfig() );
		}
		if ( snapshot.needDataChange ) {
			// 更新词云图的数据
			const { data } = await this.getConditionData();
			this.setState( {
				data: data,
			}, () => {
				// this.state.chartEl.update( this.getConfig() );
				this.state.chartEl.changeData( data );
			} );
		}
	}

	getConfig = (): any => {
		let { style } = this.props.config;

		return {
			data: this.state.data,
			wordField: 'name',
			weightField: 'value',
			colorField: 'name',
			meta: {
				name: {
					alias: 'name' ,
				},
				value: {
					alias: 'value' ,
				}
			},
			wordStyle: {
			  fontSize: [ style.minFontSize || 16, style.maxFontSize || 32 ],
			  padding: style.charSpacing || 0,
			  // 不允许文字旋转
			  rotation: 0,
			},

			// 设置区域为椭圆形
			spiral: 'archimedean',

			// 可以让每次渲染的位置相同（前提是每次的宽高一致）。
			random: () => 0.5,
			interactions: [ { type: 'marker-active' } ],
			tooltip: this.getToolTip()
		};
	};

	getToolTip = () => {
		return {
			showContent: true,
			formatter: ( datum ) => {
				let value = isNumber( this.state.precision ) ? datum.value.toFixed( this.state.precision ) : datum.value;
				return { name: datum.text, value: `${digitFormat( value, 3 ) }${this.state.dataUnit || ''}` };
			}
		};
	}

	// 获取词云图的数据
	async getConditionData() {
		const { data: dataConfigs } = this.props.config;
		if (
			dataConfigs.chartCharField &&
			dataConfigs.chartCharField.length > 0 &&
			dataConfigs.chartCharSize && dataConfigs.chartCharSize.length > 0
		) {
			const itemInfo = ( v, orderType?, desc? ) => {
				return {
					aggregateType: v.modelType === DL_TYPE ? v.aggregateType : '', //	度量的聚合类型
					formatType: v.modelType === WD_TYPE ? v.formatType : '', // 维度的聚合类型v.
					alias: v.title.trim(),
					dataType: v.dataType,
					frontendId: '',
					id: v.name,
					orderType: v.orderType, // 排序方式
					quota: v.modelType === WD_TYPE ? 'WD' : 'DL',
					symbol: '',
					type: v.type,
					value: '',
					dataUnit: v.dataUnit,
					precision: v.precision
				};
			};
			const x = dataConfigs.chartCharField.map( ( v ) => {
				return itemInfo( v );
			} );

			const y = dataConfigs.chartCharSize.map( ( v ) => {
				return itemInfo( v );
			} );

			// const conditions = this.props.config.data.filterFields ? this.props.config.data.filterFields.map( v => v.filterConditions ).flat() : [];

			// 内部筛选 condition
			const filterFieldCondition = this.props.config.data.filterFields
				? this.props.config.data.filterFields.map( ( v ) => v.filterConditions ).flat()
				: [];

			// 筛选组件的 condition
			let filterCompConditions = this.props.config.data.filterConditions || {};
			let newFilterCompConditions = [];
			Object.keys( filterCompConditions ).forEach( ( key ) => {
				newFilterCompConditions = newFilterCompConditions.concat( filterCompConditions[key] );
			} );

			const request = {
				dataConfig: {
					dataModel: {
						pageId: this.props.pageId,
						tableName: this.props.config.data.tableCode,
						x: x,
						y: y,
						conditions: filterFieldCondition.concat( this.state.dependencies, newFilterCompConditions )
					},
					needAutoRefresh: true,
					tableType: 'cloud',
				},
				type: 'word',
				tenantCode: this.props.tenantCode
			};

			let pageResponse = await getComponentData( request );
			if ( pageResponse.data && pageResponse.data.success ) {
				let { rows } = pageResponse.data.data;
				if( rows.length > 0 ) {
					this.setState( {
						dataUnit: rows[0].dataUnit || '',
						precision: rows[0].precision || ''
					} );
				}
				return { data: rows };
			}
		}

		return { data: defaultData };
	}

	render() {
		return <div id={this.props.id} style={{ height: '100%' }}></div>;
	}
}
